/*
 * Copyright (c) Huawei Device Co., Ltd. 2023. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef READER_H
#define READER_H

#include <mutex>
#include "common_utils.h"
#include "isecure_element_reader.h"

namespace OHOS {
namespace SE {
namespace OMAPI {
class SEService;
class Session;

class Reader : public std::enable_shared_from_this<Reader> {
public:
    /**
     * @brief Constructor to create the instance of Reader.
     * @param service The service for all readers and all sessions.
     * @param readName The name of this reader.
     * @param readerIface The reader proxy for IPC with the remote service.
     */
    Reader(std::weak_ptr<SEService> service, const std::string& readName, sptr<ISecureElementReader> readerIface);

    ~Reader();

    /**
     * @brief Get the name of this reader.
     * @param readerName The name of this reader.
     * @return The status code for function calling.
     */
    int GetName(std::string& readerName);

    /**
     * @brief Connects to a SE in this reader. This method prepares (initializes) the SE for communication before the
     * session object is returned (i.e. powers the SE by ICC ON if it is not already on).There might be multiple
     * sessions opened at the same time on the same reader. The system ensures the interleaving of APDUs between the
     * respective sessions. A Reader instance might not communicate with the SE during calls to openSession(), depending
     * on the implementation.
     * @param session - A Session object to be used to create channels.
     * The creation of a Session object SHALL NOT depend upon
     * the availability of the basic or logical channels.
     * @return The status code for function calling.
     */
    int OpenSession(std::shared_ptr<Session>& session);
    /**
     * @brief Check if a SE is present in this reader.
     * @param isPresent - True if the SE is present, false otherwise.
     * @return The status code for function calling.
     */
    int IsSecureElementPresent(bool &isPresent);
    /**
     * @brief Get the SE Service this reader is bound to.
     * @param service the SEService object of this reader is bound to.
     * @return Errorcode to get the SEService object.
     */
    int GetSEService(std::weak_ptr<SEService>& service);
    /**
     * @brief Close all the sessions opened on this reader. All the channels opened by all these sessions will be
     * closed.
     * @return The status code for function calling.
     */
    int CloseSessions(void);
    /**
     * @brief reset the ese
     * @param resetStatus - reset status, true succecc; false otherwise
     * @return The status code for function calling.
     */
    int Reset(bool &resetStatus);

private:
    // check the reader necessary status
    int InnerCheckReaderStatus(void);

    // used to save the reader name.
    std::string readerName_{};

    // used to save the bound service instance.
    std::weak_ptr<SEService> boundService_;

    // used to IPC with the remote reader of service.
    sptr<ISecureElementReader> readerIface_;

    // mutex for IPC calling to remote service
    std::mutex mutex_{};
};
}  // namespace OMAPI
}  // namespace SE
}  // namespace OHOS
#endif // READER_H
